package payment;

import payment.cache.CacheMock;
import payment.constant.Constants;
import payment.enums.PayWayEnum;
import payment.impl.PaymentRemoteServiceImpl;
import payment.resp.ConsultResult;
import payment.service.PaymentRemoteService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Main {
    static CacheMock<String, ConsultResult> cacheMock = new CacheMock<>();
    static PaymentRemoteService paymentRemoteService = new PaymentRemoteServiceImpl();
    //测试
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        List<String> test1 = getPayWayList();
        System.out.println("================第 1 次时间耗时:"+ (System.currentTimeMillis() - start)+"ms ===============\n结果：");
        test1.stream()
                .map(li -> PayWayEnum.matchByValue(li).getName())
                .forEach(li -> System.out.print(li +" "));
        System.out.println();
        start = System.currentTimeMillis();
        List<String> test2 = getPayWayList();
        System.out.println("================第 2 次时间耗时:"+ (System.currentTimeMillis() - start)+"ms ===============\n结果：");
        test2.stream()
                .map(li -> PayWayEnum.matchByValue(li).getName())
                .forEach(li -> System.out.print(li +" "));
        System.out.println();
        start = System.currentTimeMillis();
        List<String> test3 = getPayWayList();
        System.out.println("================第 3 次时间耗时:"+ (System.currentTimeMillis() - start)+"ms ===============\n结果：");
        test3.stream()
                .map(li -> PayWayEnum.matchByValue(li).getName())
                .forEach(li -> System.out.print(li +" "));
        System.out.println();
    }

    /**
     * 获取服务排列组合
     * @return : 可用支付方式集合
     */
    public static List<String> getPayWayList(){
        //定义收集器
        List<String> useWayCollect = new ArrayList<>(Arrays.asList(
                Constants.BALANCE,
                Constants.RED_ENVELOPE,
                Constants.COUPONS,
                Constants.VOUCHERS,
                Constants.OTHER
        ));
        List<String> canUseWayCollect = new ArrayList<>(5);
        //多线程从缓存或者远程调用接口
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
        for(int i = 0; i < useWayCollect.size();i++) {
            String li = useWayCollect.get(i);
            Runnable runnable = ()-> {
                //缓存中拿值
                ConsultResult hasUse = cacheMock.get(li);
                //值为空则远程调用
                if (Objects.isNull(hasUse)) {
                    hasUse = paymentRemoteService.isEnabled(li);
                    //写缓存
                    cacheMock.set(li, hasUse);
                }
                if (hasUse.getIsEnable()) {
                    canUseWayCollect.add(li);
                }
            };
            executor.execute(runnable);
        }
        try {
            executor.shutdown();
            if(!executor.awaitTermination(4000L, TimeUnit.MILLISECONDS)){
                executor.shutdownNow();
            }
        }catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
        //返回结果
        return canUseWayCollect;
    }


}